//  this library.
import 'dart:async';
import 'dart:convert';

import 'package:hktk_app/ienum/practice/ct_enum.dart';
import 'package:hktk_app/ienum/question/first_type_enum.dart';
import 'package:hktk_app/ienum/subject/add_frequency_type.dart';

import 'package:hktk_app/ienum/subject/collection_type_enum.dart';
import 'package:hktk_app/model/page/resource_page_model.dart';
import 'package:hktk_app/model/practice/practice_question_model.dart';
import 'package:hktk_app/model/subject/chapter_model.dart';
import 'package:hktk_app/model/subject/note_model.dart';
import 'package:hktk_app/model/subject/note_vo_model.dart';
import 'package:hktk_app/model/subject/paper_model.dart';
import 'package:hktk_app/model/subject/paper_detail_model.dart';
import 'package:hktk_app/model/subject/question_collection_model.dart';
import 'package:hktk_app/model/subject/rank_error_model.dart';
import 'package:hktk_app/model/subject/submit_paper_model.dart';
import 'package:hktk_app/model/subject/upload_answer_model.dart';
import 'package:hktk_app/model/subject/upload_collection_model.dart';
import 'package:hktk_app/model/subject/records_model.dart';
import 'package:hktk_app/model/subject/upload_save_model.dart';
import 'package:hktk_app/util/dao_util.dart';
import 'package:hktk_app/util/encrypt_util.dart';

/// 金刚区相关接口
class SubjectDao {
  /// 根据栏目拉取章节
  static Future<List<ChapterModel>> chapterByColumnId({
    required String columnId,
    required int categoryId,
  }) async {
    String url =
        "/exam/chapter/chapter-by-columnId?columnId=$columnId&categoryId=$categoryId";
    // 发送请求
    var data = await httpGET(url: url, tips: "根据栏目拉取章节");
    if (data is List<dynamic>) {
      return data.map((dynamic map) => ChapterModel.fromJson(map)).toList();
    } else {
      return <ChapterModel>[];
    }
  }

  /// 获取子章节
  static Future<List<ChapterModel>> childChapter({
    required String columnId,
    required String pId,
    bool qCount = true,
    bool setLeaf = true,
  }) async {
    String url =
        "/exam/chapter/child-chapter?columnId=$columnId&pid=$pId&qcount=$qCount&setLeaf=$setLeaf";
    // 发送请求
    var data = await httpGET(url: url, tips: "获取子章节");
    if (data is List<dynamic>) {
      return data.map((dynamic map) => ChapterModel.fromJson(map)).toList();
    } else {
      return <ChapterModel>[];
    }
  }

  // industryCode：行业id，
  // examId：考试id，
  // categoryId：科目id，
  // chapterId：章节id，
  // recordsType：类型，
  /// 获取章节的做题数统计
  static Future<UploadSaveModel> chapterRecords({
    required String industryCode,
    required String examId,
    required int categoryId,
    required String chapterId,
    CtEnum recordsType = CtEnum.chapter,
  }) async {
    String url =
        "/exam/records/chapter-records?industryCode=$industryCode&examId=$examId&categoryId=$categoryId&chapterId=$chapterId&recordsType=${recordsType.name}";
    // 发送请求
    var data = await httpGET(url: url, tips: "获取章节的做题数统计");
    return UploadSaveModel.fromJson(data);
  }

  /// 获取章节的做题数统计-章节ids集合
  static Future<Map<String, dynamic>> chapterRecordsIds({
    required String industryCode,
    required String examId,
    required int categoryId,
    required List<String> chapterIds,
    CtEnum recordsType = CtEnum.chapter,
  }) async {
    String url =
        "/exam/records/chapter-records-ids?industryCode=$industryCode&examId=$examId&categoryId=$categoryId&recordsType=${recordsType.name}";
    for (String id in chapterIds) {
      url = "$url&chapterIds=$id";
    }
    // 发送请求
    var data = await httpGET(url: url, tips: "获取章节的做题数统计-章节ids集合");
    return data;
  }

  // collectionTypeEnum：类型，
  // industryCode：行业id，
  // examId：考试id，
  // categoryId：科目id，
  // columnId：栏目id，
  // id：章节id，
  // trueV：判断是否是考试模式，true：练习模式，false：考试模式
  /// 获取试题集合，
  static Future<QuestionCollectionModel> questionCollection({
    required CollectionTypeEnum collectionTypeEnum,
    required String industryCode,
    required String examId,
    required int categoryId,
    required String columnId,
    required String id,
    required bool trueV,
  }) async {
    // 发送数据
    Map<String, dynamic> params = {
      "collectionType": collectionTypeEnum.name,
      "industryCode": industryCode,
      "examId": examId,
      "categoryId": categoryId,
      "columnId": columnId,
      "id": id,
      "true": trueV,
    };
    // 加密
    String encode = jsonEncode(params);
    String encryptStr = await EncryptUtil.esaEncrypt(encode);
    // 路径
    String url = "/exam/records/question-collection";
    // 发送请求
    var data = await httpPOST(
      url: url,
      paramsStr: encryptStr,
      tips: "获取试题集合",
      custom: false,
      encryptionType: "rsa",
    );
    return QuestionCollectionModel.fromJson(data);
  }

  // size：分页条数，
  // current：页数，
  // columnId：栏目id，
  // countDetail：？，
  /// 根据栏目拉取试卷
  static Future<ResourcePageModel<PaperModel>> paperByColumnId({
    required int size,
    required int current,
    required String columnId,
    required bool countDetail,
  }) async {
    String url =
        "/exam/paper/paper-by-columnId?size=$size&current=$current&columnIds=$columnId&countDetail=$countDetail";
    // 发送请求
    var data = await httpGET(url: url, tips: "根据栏目拉取试卷");
    return ResourcePageModel.fromJson(data);
  }

  /// 查看试卷详情
  static Future<PaperDetailModel> paperDetail({
    required String id,
  }) async {
    String url = "/exam/paper/detail?id=$id";
    // 发送请求
    var data = await httpGET(url: url, tips: "查看试卷详情");
    return PaperDetailModel.fromJson(data);
  }

  // industryCode：行业id，
  // examId：考试id，
  // categoryId：科目id，
  // paperId：试卷id，
  // recordsId：记录id，
  // columnId：栏目id，
  // result：是否返回生成试卷的试题集合-默认：true，
  // strict：强制创建-默认：false，
  // practiceModel：是否时试卷练习模式-默认：false，
  /// 试卷库创建试卷记录
  static Future<RecordsModel> generatePaperRecords({
    required String industryCode,
    required String examId,
    required int categoryId,
    required String paperId,
    String? recordsId,
    required String columnId,
    bool result = true,
    bool strict = false,
    bool practiceModel = false,
  }) async {
    Map<String, dynamic> params = {
      "industryCode": industryCode,
      "examId": examId,
      "categoryId": categoryId,
      "paperId": paperId,
      "recordsId": recordsId,
      "columnId": columnId,
      "result": result,
      "strict": strict,
      "practiceModel": practiceModel,
    };
    String url = "/exam/paper-records/generate-paper-records";
    // 发送请求
    var data = await httpPOST(
      url: url,
      tips: "试卷库创建试卷记录",
      params: params,
      contentType: cTypeX,
    );
    return RecordsModel.fromJson(data);
  }

  /// 生产随机试卷记录
  static Future<RecordsModel> generateRandomRecords({
    required String industryCode,
    required String examId,
    required int categoryId,
    required String columnId,
    bool result = true,
  }) async {
    Map<String, dynamic> params = {
      "categoryId": categoryId,
      "columnId": columnId,
    };
    // 加密
    String encode = jsonEncode(params);
    String encryptStr = await EncryptUtil.esaEncrypt(encode);
    String url = "/exam/paper-records/generate-random-records";
    // 发送请求
    var data = await httpPOST(
      url: url,
      paramsStr: encryptStr,
      tips: "生产随机试卷记录",
      custom: false,
      encryptionType: "rsa",
    );
    return RecordsModel.fromJson(data);
  }

  /// 提交用户做题答案，校验答案正确性
  static Future<RecordModel> pushQuestionRightCheck({
    required String industryCode,
    required String examId,
    required int categoryId,
    required String collectId,
    required String qid,
    required FirstTypeEnum typeEnum,
    required String as,
    String? answer,
    String? clientRightAnswer,
  }) async {
    Map<String, dynamic> params = {
      "industryCode": industryCode,
      "examId": examId,
      "categoryId": categoryId,
      "collectId": collectId,
      "qid": qid,
      "type": typeEnum.name,
      "as": as,
    };
    if (answer != null) {
      params["answer"] = answer;
    } else {
      params["clientRightAnswer"] = clientRightAnswer;
    }
    // 加密
    String encode = jsonEncode(params);
    String encryptStr2 = EncryptUtil.aesEncrypt(data: encode);
    // 路径
    String url = "/exam/records/push-question-right-check";
    // 发送请求
    var data = await httpPOST(
      url: url,
      tips: "提交用户做题答案，校验答案正确性",
      paramsStr: encryptStr2,
      custom: false,
      encryptionType: "aes",
    );
    return RecordModel.fromJson(data);
  }

  // industryCode：行业code
  // examId：考试id
  // categoryId：科目id
  // collectId：集合id
  // collectName：集合名称
  // recordsType：集合类型
  // removeIds：移除收藏的ids
  // data：章节新增收藏记录{key:试题id，value：item}
  // cdata：章节收藏记录{key:试题id，value：时间戳}
  /// 集合做题退出时保存试题收藏数据
  static Future<void> pushNewCollect({
    required String industryCode,
    required String examId,
    required int categoryId,
    required String collectId,
    required String collectName,
    required CtEnum recordsType,
    required List<String> removeIds,
    required Map<String, UploadCollectionModel> data,
    required Map<String, int> cdata,
  }) async {
    Map<String, dynamic> params = {
      "industryCode": industryCode,
      "examId": examId,
      "categoryId": categoryId,
      "collectId": collectId,
      "collectName": collectName,
      "recordsType": recordsType.name,
      "removeIds": removeIds,
      "data": data,
      "cdata": cdata,
    };
    String url = "/exam/records/push-new-collect";
    // 发送请求
    await httpPOST(
      url: url,
      params: params,
      tips: "集合做题退出时保存试题收藏数据",
    );
  }

  // industryCode：行业code
  // examId：考试id
  // categoryId：科目id
  // collectId：集合id
  // recordsType：试题类型
  // collectName：集合名称
  // lastId：最后做题id
  // totalCount：当前试题总数
  // data：章节做题记录{key:试题id，value：item}
  /// 练习模式退出时提交答案
  static Future<void> pushChapterAnswer({
    required String industryCode,
    required String examId,
    required int categoryId,
    required String collectId,
    required CtEnum recordsType,
    required String collectName,
    required String lastId,
    required int totalCount,
    required Map<String, UploadAnswerModel> data,
  }) async {
    Map<String, dynamic> params = {
      "industryCode": industryCode,
      "examId": examId,
      "categoryId": categoryId,
      "collectId": collectId,
      "recordsType": recordsType.name,
      "collectName": collectName,
      "lastId": lastId,
      "totalCount": totalCount,
      "data": data,
    };
    String url = "/exam/records/push-chapter-answer";
    // 发送请求
    await httpPOST(
      url: url,
      params: params,
      tips: "练习模式退出时提交答案",
    );
  }

  // industryCode：行业code
  // examId：考试id
  // categoryId：科目id
  // collectId：集合id
  // collectName：集合名称
  // recordsType：集合类型
  // data：章节做题记录{key:试题id，value：item}
  /// 集合做题退出是保存错题数据
  static Future<void> pushCollectErrorAnswer({
    required String industryCode,
    required String examId,
    required int categoryId,
    required String collectId,
    required String collectName,
    required CtEnum recordsType,
    required Map<String, UploadCollectionModel> data,
  }) async {
    Map<String, dynamic> params = {
      "industryCode": industryCode,
      "examId": examId,
      "categoryId": categoryId,
      "collectId": collectId,
      "collectName": collectName,
      "recordsType": recordsType.name,
      "data": data,
    };
    String url = "/exam/records/push-collect-error-answer";
    // 发送请求
    await httpPOST(
      url: url,
      params: params,
      tips: "集合做题退出是保存错题数据",
    );
  }

  // industryCode：行业id
  // examId：考试id
  // categoryId：科目id
  // collectId：集合id
  // recordsType：试卷类型
  // dc：新增/减少 做题数量
  // er：新增/减少 错题数量
  // cc：新增/减少 收藏试题数量
  /// 保存章节集合统计数据
  static Future<UploadSaveModel> saveChapterRecords({
    required String industryCode,
    required String examId,
    required int categoryId,
    required String collectId,
    required CtEnum recordsType,
    required UploadSaveModel data,
  }) async {
    Map<String, dynamic> params = {
      "industryCode": industryCode,
      "examId": examId,
      "categoryId": categoryId,
      "collectId": collectId,
      "recordsType": recordsType.name,
      "data": data,
    };
    String url = "/exam/records/save-chapter-records";
    // 发送请求
    var dataV = await httpPOST(
      url: url,
      params: params,
      tips: "保存章节集合统计数据",
    );
    if (dataV == null) {
      return UploadSaveModel(dc: 0, ec: 0, cc: 0);
    }
    return UploadSaveModel.fromJson(dataV);
  }

  // industryCode: 行业id,
  // examId: 考试id,
  // categoryId: 科目id,
  // recordsId: 记录id,
  // lastId: 最后做题id,
  // seconds: 做题时间,
  // cn: 试卷名称,
  // totalCount: totalCount,
  // recordsType: 试卷类型,
  // data: 上传数据,
  /// 保存试卷做题记录，只是保存，不交卷
  static Future<void> savePaperAnswer({
    required String industryCode,
    required String examId,
    required int categoryId,
    required String recordsId,
    required String lastId,
    required int seconds,
    required String cn,
    required int totalCount,
    required CtEnum recordsType,
    required Map<String, RecordModel> data,
  }) async {
    Map<String, dynamic> params = {
      "industryCode": industryCode,
      "examId": examId,
      "categoryId": categoryId,
      "recordsId": recordsId,
      "lastId": lastId,
      "seconds": seconds,
      "cn": cn,
      "totalCount": totalCount,
      "recordsType": recordsType.name,
      "data": data,
    };
    String url = "/exam/records/save-paper-answer";
    // 发送请求
    await httpPOST(
      url: url,
      params: params,
      tips: "保存试卷做题记录，只是保存，不交卷",
    );
  }

  // industryCode : 行业id,
  // examId : 考试id,
  // categoryId : 科目id,
  // recordsId : 试卷记录id,
  // seconds : 时间,
  // imageCheck : imageCheck,
  // timestamp : timestamp,
  // sign : sign,
  // lastId : 最后做题id,
  // data : 做题记录{key:试题id，value：item},
  /// 试卷交卷
  static Future<SubmitPaperModel> submitPaperAnswer({
    required String industryCode,
    required String examId,
    required int categoryId,
    required String recordsId,
    required int seconds,
    required bool imageCheck,
    required int timestamp,
    required String sign,
    required String lastId,
    required Map<String, dynamic> data,
  }) async {
    Map<String, dynamic> params = {
      "industryCode": industryCode,
      "examId": examId,
      "categoryId": categoryId,
      "recordsId": recordsId,
      "seconds": seconds,
      "imageCheck": imageCheck,
      "timestamp": timestamp,
      "sign": sign,
      "lastId": lastId,
      "data": data,
    };
    String url = "/exam/records/submit-paper-answer";
    // 发送请求
    var dataV = await httpPOST(
      url: url,
      params: params,
      tips: "试卷交卷",
    );
    return SubmitPaperModel.fromJson(dataV);
  }

  // industryCode：行业id，
  // examId：考试id，
  // categoryId：科目id，
  // recordsId：试卷记录id，
  // structure：收藏标识，是否收藏试卷，
  /// 内部打开试卷结果并查看
  static Future<SubmitPaperModel> paperRecordsInlineResult({
    required String industryCode,
    required String examId,
    required int categoryId,
    required String recordsId,
    bool structure = true,
  }) async {
    String url =
        "/exam/paper-records/paper-records-inline-result?industryCode=$industryCode&examId=$examId&categoryId=$categoryId&recordsId=$recordsId&structure=$structure";
    // 发送请求
    var data = await httpGET(url: url, tips: "内部打开试卷结果并查看");
    return SubmitPaperModel.fromJson(data);
  }

  // industryCode：行业id，
  // examId：考试id，
  // categoryId：科目id，
  // recordsType：类型，
  // haveCollect：haveCollect，
  // id：对应的试卷/章节id，
  /// 删除集合做题/错题记录
  static Future<UploadSaveModel> cleamCollectRecords({
    required String industryCode,
    required String examId,
    required int categoryId,
    required CtEnum recordsType,
    required bool haveCollect,
    required String id,
  }) async {
    Map<String, dynamic> params = {
      "industryCode": industryCode,
      "examId": examId,
      "categoryId": categoryId,
      "recordsType": recordsType.name,
      "haveCollect": haveCollect,
      "id": id,
    };
    String url = "/exam/records/clean-collect-records/$id";
    // 发送请求
    var data = await httpDelete(
      url: url,
      params: params,
      tips: "删除集合做题/错题记录",
    );
    return UploadSaveModel.fromJson(data);
  }

  /// 获取考试或者科目下错题排行
  static Future<List<RankErrorModel>> categoryRankError({
    required String examId,
    required int categoryId,
    int size = 100,
    int current = 1,
    String keyword = "",
    String qid = "",
  }) async {
    String url =
        "/exam/records/category-rank-error?examId=$examId&categoryId=$categoryId&size=$size&current=$current";
    if (keyword != "") {
      url = "$url&keyword=$keyword";
    }
    if (qid != "") {
      url = "$url&qid=$qid";
    }
    // 发送请求
    var data = await httpGET(url: url, tips: "获取考试或者科目下错题排行");
    var records = data["records"];
    if (records is List<dynamic>) {
      return records.map((v) => RankErrorModel.fromJson(v)).toList();
    } else {
      return <RankErrorModel>[];
    }
  }

  /// 获取考试或者科目下做题排行题
  static Future<List<RankErrorModel>> categoryRank({
    required String examId,
    required int categoryId,
    int size = 100,
    int current = 1,
    String keyword = "",
    String qid = "",
  }) async {
    String url =
        "/exam/records/category-rank?examId=$examId&categoryId=$categoryId&size=$size&current=$current";
    if (keyword != "") {
      url = "$url&keyword=$keyword";
    }
    if (qid != "") {
      url = "$url&qid=$qid";
    }
    // 发送请求
    var data = await httpGET(url: url, tips: "获取考试或者科目下做题排行题");
    var records = data["records"];
    if (records is List<dynamic>) {
      return records.map((v) => RankErrorModel.fromJson(v)).toList();
    } else {
      return <RankErrorModel>[];
    }
  }

  // current：页数，
  // size：条数，
  // questionId：试题id，
  // relationId：关联id，
  /// 获取笔记列表
  static Future<ResourcePageModel<NoteVoModel>> getNoteList({
    required int current,
    required int size,
    required String questionId,
    String? relationId,
  }) async {
    String url =
        "/exam/note/get-note-list?current=$current&size=$size&questionId=$questionId";
    if (relationId != null) {
      url = "$url&relationId=$relationId";
    }
    // 发送请求
    var data = await httpGET(url: url, tips: "获取笔记列表");
    if (data != null) {
      return ResourcePageModel.fromJson(data);
    }
    return ResourcePageModel();
  }

  /// 发表笔记
  static Future<NoteModel> noteUpdate({required NoteModel noteModel}) async {
    String url = "/exam/note/update";
    // 发送请求
    var data = await httpPOST(
      url: url,
      params: noteModel.toJson(),
      tips: "发表笔记",
    );
    if (data != null) {
      return NoteModel.fromJson(data);
    }
    return NoteModel();
  }

  /// 增加下载次数、查看次数
  static Future<dynamic> addFrequency({
    required AddFrequencyType type,
    required String id,
  }) async {
    Map<String, dynamic> params = {
      "type": type.name,
      "id": id,
    };
    String url = "/material/info/add-frequency";
    // 发送请求
    await httpPut(
      url: url,
      params: params,
      tips: "增加下载次数、查看次数",
    );
  }
}
